#pragma once
#include <memory>
#include <functional>
#include <condition_variable>
#include <queue>
#include <atomic>
#include <thread>
#include <mutex>
#include <new> // 添加此头文件以支持 placement new

namespace common_component
{

    template <typename T>
    class ObjectPool
    {
    public:
        using Ptr = std::shared_ptr<T>;
        using ConstructFunc = std::function<std::unique_ptr<T>()>;
        explicit ObjectPool(size_t initial_size = 0, size_t max_size = 0, size_t high_water_mark = 0)
            : max_size_(max_size), high_water_mark_(high_water_mark ? high_water_mark : initial_size / 2), allocated_count_(0), available_count_(0), total_created_(0), total_recycled_(0), hit_count_(0), miss_count_(0), initial_size_(initial_size), preallocation_in_progress_(false)
        {
            // if (initial_size > 0) {
            //     preallocate(initial_size);
            // }
        }

        template <typename... Args>
        Ptr acquire(Args &&...args)
        {
            // 延迟初始化：首次调用时进行预分配
            static std::once_flag init_flag;
            std::call_once(init_flag, [this, &args...]()
                           {
            if (initial_size_ > 0) {
                // 使用首次acquire的参数进行预分配
                preallocate(initial_size_, args...);
            } });

            // 快速路径：尝试从池中获取
            std::unique_ptr<T> obj;
            {
                std::unique_lock<std::mutex> lock(mutex_);
                if (!pool_.empty())
                {
                    obj = std::move(pool_.front());
                    pool_.pop();
                    available_count_--;
                    hit_count_++;
                }
            } // 锁在这里释放

            // 如果成功获取到对象
            if (obj)
            {
                // 重用对象的安全方法
                reinitializeObject(obj, std::forward<Args>(args)...);
                return wrapWithDeleter(std::move(obj));
            }

            // 慢速路径：创建新对象
            miss_count_++;

            // 检查是否超过最大限制
            if (max_size_ > 0 && allocated_count_ >= max_size_)
            {
                // 等待对象返回 - 使用while循环防止伪唤醒和竞态条件
                std::unique_lock<std::mutex> lock(mutex_);

                while (pool_.empty() && !shutdown_)
                {
                    cv_.wait(lock);
                }

                if (shutdown_)
                {
                    return nullptr;
                }

                // 在锁保护下直接获取对象，避免递归
                if (!pool_.empty())
                {
                    obj = std::move(pool_.front());
                    pool_.pop();
                    available_count_--;
                    hit_count_++;

                    // 重用对象的安全方法
                    reinitializeObject(obj, std::forward<Args>(args)...);
                    return wrapWithDeleter(std::move(obj));
                }

                // 如果仍然没有对象（理论上不应该发生），返回nullptr
                return nullptr;
            }

            // 创建新对象
            obj = std::make_unique<T>(std::forward<Args>(args)...);
            allocated_count_++;
            total_created_++;

            // 检查是否需要异步预分配更多对象
            if (available_count_ < high_water_mark_ && !preallocation_in_progress_.load())
            {
                // 计算合理的预分配批次大小
                size_t batch_size = std::max(initial_size_, static_cast<size_t>(2)); // 至少预分配2个

                // 确保不超过最大限制
                if (max_size_ > 0)
                {
                    // 使用饱和减法，防止 allocated_count_ 已经 >= max_size_ 时出现无符号下溢
                    size_t current_allocated = allocated_count_.load(std::memory_order_relaxed);
                    size_t remaining_capacity =
                        (current_allocated < max_size_) ? (max_size_ - current_allocated) : 0;
                    batch_size = std::min(batch_size, remaining_capacity);
                }

                // 避免预分配过多，最多补充到高水位
                size_t needed =
                    (high_water_mark_ > available_count_) ? (high_water_mark_ - available_count_) : 0;
                batch_size = std::min(batch_size, needed);

                if (batch_size > 0)
                {
                    preallocation_in_progress_.store(true);
                    std::thread([this, batch_size, args...]()
                                {
                    preallocate(batch_size, args...);
                    preallocation_in_progress_.store(false); })
                        .detach();
                }
            }

            return wrapWithDeleter(std::move(obj));
        }
        template <typename... Args>
        Ptr tryAcquire(Args &&...args)
        {
            std::unique_ptr<T> obj;
            bool from_pool = false;

            // 缩小锁粒度：只在操作共享数据时加锁
            {
                std::unique_lock<std::mutex> lock(mutex_);

                if (!pool_.empty())
                {
                    obj = std::move(pool_.front());
                    pool_.pop();
                    available_count_--;
                    hit_count_++;
                    from_pool = true;
                }
                else
                {
                    // 检查是否可以创建新对象
                    if (max_size_ > 0 && allocated_count_ >= max_size_)
                    {
                        miss_count_++;
                        return nullptr;
                    }
                    // 预先增加计数，防止竞态条件
                    allocated_count_++;
                    total_created_++;
                    miss_count_++;
                }
            } // 锁在这里释放

            // 在锁外执行可能耗时的操作
            if (from_pool)
            {
                // 重用对象的安全方法
                reinitializeObject(obj, std::forward<Args>(args)...);
            }
            else
            {
                // 在锁外创建新对象
                obj = std::make_unique<T>(std::forward<Args>(args)...);
            }

            return wrapWithDeleter(std::move(obj));
        }
        template <typename... Args>
        void preallocate(size_t count, Args &&...args)
        {
            std::unique_lock<std::mutex> lock(mutex_);
            size_t to_allocate = count;
            if (max_size_ > 0)
            {
                to_allocate = std::min(count, max_size_ - allocated_count_);
            }
            lock.unlock();
            for (size_t i = 0; i < to_allocate; ++i)
            {
                auto obj = std::make_unique<T>(std::forward<Args>(args)...);
                lock.lock();
                pool_.push(std::move(obj));
                allocated_count_++;
                available_count_++;
                lock.unlock();
            }
        }
        /**
         * @brief 获取统计信息
         */
        struct Statistics
        {
            size_t pool_size;       // 池中可用对象数
            size_t allocated_count; // 已分配总数
            size_t total_created;   // 总创建次数
            size_t total_recycled;  // 总回收次数
            size_t hit_count;       // 命中次数
            size_t miss_count;      // 未命中次数
            double hit_rate;        // 命中率
            double recycle_rate;    // 回收率
        };
        Statistics getStatistics() const
        {
            std::unique_lock<std::mutex> lock(mutex_);
            Statistics stats;
            stats.pool_size = pool_.size();
            stats.allocated_count = allocated_count_;
            stats.total_created = total_created_;
            stats.total_recycled = total_recycled_;
            stats.hit_count = hit_count_;
            stats.miss_count = miss_count_;
            size_t total_requests = hit_count_ + miss_count_;
            stats.hit_rate =
                total_requests > 0 ? static_cast<double>(hit_count_) / total_requests : 0.0;
            stats.recycle_rate =
                total_created_ > 0 ? static_cast<double>(total_recycled_) / total_created_ : 0.0;
            return stats;
        }
        void clear()
        {
            std::unique_lock<std::mutex> lock(mutex_);
            while (!pool_.empty())
            {
                pool_.pop();
            }
            allocated_count_ = 0;
            available_count_ = 0;
        }
        /**
         * @brief 主动收缩池中空闲对象
         *
         * 当池中的可用对象数量超过
         *  @param target_size（默认为 high_water_mark_）时，
         * 该方法会销毁多余的对象以释放内存，但不会影响正在被外部持有的对象。
         * 该方法是线程安全的，可被后台维护线程或用户手动调用。
         *
         * @param target_size 希望保留的空闲对象数量（0 表示使用 high_water_mark_）。
         */
        void trim(size_t target_size = 0)
        {
            std::vector<std::unique_ptr<T>> to_destroy; // 锁外销毁，缩短临界区
            {
                std::unique_lock<std::mutex> lock(mutex_);
                size_t desired = (target_size == 0) ? high_water_mark_ : target_size;

                while (!pool_.empty() && pool_.size() > desired)
                {
                    to_destroy.emplace_back(std::move(pool_.front()));
                    pool_.pop();
                    --allocated_count_;
                    --available_count_;
                }
            } // unlock here

            // 锁外自动析构 vector 中的 unique_ptr，释放对象内存
        }
        void shutdown()
        {
            std::unique_lock<std::mutex> lock(mutex_);
            shutdown_ = true;
            cv_.notify_all();
        }
        ~ObjectPool()
        {
            shutdown();
            clear();
        }
        Ptr wrapWithDeleter(std::unique_ptr<T> obj)
        {
            T *raw = obj.release();
            return Ptr(raw, [this](T *ptr)
                       { returnObject(std::unique_ptr<T>(ptr)); });
        }
        void returnObject(std::unique_ptr<T> obj)
        {
            if (!obj)
            {
                return;
            }
            std::unique_lock<std::mutex> lock(mutex_);
            if (shutdown_ || (max_size_ > 0 && pool_.size() >= max_size_))
            {
                allocated_count_--;
                return;
            }
            pool_.push(std::move(obj));
            available_count_++;
            total_recycled_++;
            cv_.notify_one();
        }

        // SFINAE 检测：是否有无参 Reset 方法
        template <typename U>
        struct has_reset
        {
            template <typename V>
            static auto test(int)
                -> decltype((std::declval<V>().Reset(), std::true_type{}), void(), std::true_type{})
            {
                return std::true_type{};
            }
            template <typename>
            static std::false_type test(...)
            {
                return std::false_type{};
            }
            static constexpr bool value = decltype(test<U>(0))::value;
        };

        // SFINAE 检测：是否有带参数的 Reset 方法
        template <typename U, typename... ResetArgs>
        struct has_reset_with_args
        {
            template <typename V>
            static auto test(int)
                -> decltype((std::declval<V>().Reset(std::declval<ResetArgs>()...), std::true_type{}),
                            void(), std::true_type{})
            {
                return std::true_type{};
            }
            template <typename>
            static std::false_type test(...)
            {
                return std::false_type{};
            }
            static constexpr bool value = decltype(test<U>(0))::value;
        };

        // 重用对象的安全方法
        template <typename... Args>
        void reinitializeObject(std::unique_ptr<T> &obj, Args &&...args)
        {
            T *ptr = obj.get();
            if (!ptr)
                return;

            // 策略1：优先使用带参数的Reset方法
            if constexpr (has_reset_with_args<T, Args...>::value)
            {
                ptr->Reset(std::forward<Args>(args)...);
            }
            // 策略2：使用无参Reset方法（向后兼容）
            else if constexpr (has_reset<T>::value)
            {
                ptr->Reset();
            }
            // 策略3：最后使用placement new重构造
            else
            {
                try
                {
                    ptr->~T();                                // 先析构
                    new (ptr) T(std::forward<Args>(args)...); // 重新构造
                }
                catch (...)
                {
                    // 如果构造失败，确保对象处于可析构状态
                    // 这里可以考虑将obj重置为nullptr，让unique_ptr处理
                    obj.reset();
                    throw; // 重新抛出异常
                }
            }
        }

    private:
        mutable std::mutex mutex_;
        std::condition_variable cv_;
        std::queue<std::unique_ptr<T>> pool_;
        size_t max_size_;
        size_t high_water_mark_;
        size_t initial_size_;
        std::atomic<size_t> allocated_count_;
        std::atomic<size_t> available_count_;
        std::atomic<size_t> total_created_;
        std::atomic<size_t> total_recycled_;
        std::atomic<size_t> hit_count_;
        std::atomic<size_t> miss_count_;
        std::atomic<size_t> shutdown_{false};
        std::atomic<bool> preallocation_in_progress_;
    };
} // common_component